在程式執行時,我們可以透過if判斷、guard與switch case來改變程式執行流程。
if判斷式基本有三種變化
// 第一種
if number == 1 {
}
// 第二種
if number == 1 {
} else {
}
// 第三種
if number == 1 {
} else if number == 2 {
}
如果if後面的判斷式包含了兩個以上的邏輯判斷,可用以下符號作邏輯運算
guard 語句,類似於 if 語句,使用 guard 語句來要求一個條件必須是真才能繼續執行後面的程式碼。與 if 語句不同, guard 語句總是有一個 else 分句—— else 分句裡的代碼會在條件不為真的時候執行。
雖然這也可以靠if else來完成,但是guard有「把守、確保」的意思,如果我們要確保某些事情發生或不發生,使用guard讓程式碼的可讀性可以更加明暸。
func securityCheck(someone: String) {
guard someone == "have a key" else {
print("You can't pass.")
return
}
print("open the door")
}
var Charlie = "have a key"
securityCheck(someone: Charlie) //印出"open the door"
上例可以清楚解釋 「當某個人有鑰匙的時候才開門」
switch case的用法如下,如果case裡有程式碼的話,break可以省略,也就是說:
let city = "TNN"
switch city {
case "TPE":
print("Taipei")
case "TXG":
print("Taichung")
case "TNN":
print("Tainan") //匹配成功,印出"Tainan"後跳離switch
default:
print("the other city")
}
除此之外,也可以在case中宣告暫時性的常數或變數,並用where語句來做條件限制,Ex:
//判別point是否在x=y或x=-y線上
let point = (2,4)
switch point {
case let (x, y) where x == y:
print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
print("(\(x), \(y)) is just some arbitrary point")
}
主要是將一個程式區段當成函數的參數或是類別的屬性來傳遞,Ex:
func inc (value: Int) -> Int {
return value + 1
}
func dec (value: Int) -> Int {
return value - 1
}
func f(_ value: Int, op: (Int) -> Int) -> Int {
return op(value)
}
f(10, op: inc) //印出11
f(20, op: dec) //印出19
先來看三個實作的函數
這邊再把op的資料型態拿出來看一下(Int)->Int,也就是op本身也要是一個函數,而且該函數必須要符合『輸入值是Int型態,輸出值是Int型態』,剛好我們實作的inc、dec恰好符合這個形態,因此op的後面可以直接引用這兩個函數。
如果我們事先沒有給予inc或是dec一個函數名稱,而是將整個函數內容寫進op裡面,這種語法就稱為 inline closure,EX:
let n = f(5, op: {(value) -> Int in return value * value})
print(n) //印出 25
op位置的closure可以放到f()函數的最後面,這樣的語法就稱為trailing closure,EX:
let n = f(5) {(value) -> Int in return value * value}
print(n) //印出 25
Swift允許使用 $0、$1、$2來代替closure中的參數名稱,而且回傳值可以自動判定,因此f()函數中的inline closure可以簡寫成:
let n = f(5) {
return $0 * $0
}
print(n) //印出 25
Swift中最簡單的類別寫法如下,其中init()函數為類別實體化時會呼叫的函數,若類別不需要初始化,這個函數可以省略不寫。
class someClass: NSObject {
override init() {
}
}
當然我們可以自訂我們的init()函數
class someClass: NSObject {
override init() {
}
init(_ value: Int) {
super.init()
}
}
在類別中宣告的屬性或函數,區分為instance等級與class等級。兩者差別在instance等級要實體化後才可以使用它,而class等級則不用實體化即可使用。在屬性或是函數的宣告前面加入static,就代表它們是class等級。
class SomeClass: NSObject {
let someStr = "這是一個instance 等級屬性"
static let otherStr = "這是一個class 等級屬性"
func someFuction() {
print("這是一個instance 等級屬性")
}
static func otherFunction() {
print("這是一個class 等級屬性")
}
}
let testclass = SomeClass() //類別實體化
testclass.someStr
testclass.someFuction()
SomeClass.otherStr //因為otherStr是class屬性,所以可以直接調用
SomeClass.otherFunction()
Swift中所有屬性都包含getter和setter函數,只是大部分我們都不需要覆寫它們,但某些情況我們要將值放到屬性中或是取出時需要先處理一下,這時候我們就要覆寫一下getter和setter函數了。
class newClass {
var value: Int = 0
var doubleValue: Int {
get {
return value
}
set(newValue) {
value = newValue * 2
}
}
}
let testNewClass = newClass()
testNewClass.doubleValue = 10
print(testNewClass.doubleValue) //印出 20
並不是每次覆寫都要修改getter和setter,可以依需要指修改getter或setter,所以上例可以直接改寫getter就好
class newClass {
var value: Int = 0
var doubleValue: Int {
get {
return value * 2
}
}
}
let testNewClass = newClass()
testNewClass.value = 10 //注意這裡是設定value,而不是doubleValue
print(testNewClass.doubleValue) //印出 20
每個函數都有個函數名稱,用來描述函數執行的任務。當你定義一個函數時,你可以定義一個或多個有名字和資料型態的值,作為函數的輸入(內部參數)(parameters)。
要使用一個函數時,你用函數名「呼叫」,並傳給它匹配的輸入值(外部參數)(arguments)。一個函數的外部參數必須與函數的參數表裡參數的順序一致。
func whatTimeIsIt (time t: Int) {
print("Now is \(t) o'clock.")
}
whatTimeIsIt(time: 12) //印出"It is 12 o'clock."
上述例子中
函數名:whatTimeIsIt
外部參數名: time
內部參數名: t
Swift為了讓程式碼更方便閱讀,要求使用者在呼叫函數時,務必填寫外部參數名,否則會編譯錯誤,而函數內為求程式碼精簡,內部參數名通常會用簡稱或是縮寫。
Argument又翻譯成 「引數」,我稱之為『外部參數』,實際全名應為”actual argument” 才是那個實際的值
parameter又翻譯成「參數」,我稱之為『內部參數』,實際全名應為”formal parameter” 指的就是那個用來代表參數的符號而已
函數也可以定義任意資料型態的值作為函數執行結束的回傳值。只需要在函數宣告後方加上「->」符號與傳回值的資料型態,並在函數中使用return傳回即可。
func driverLicense (age a: Int) -> Bool {
if a > 17 {
return true
} else {
return false
}
}
driverLicense(age: 19) //印出true,因為大於17歲所以可以考取駕照
part II 就先到這告一個段落,明天還有最後一篇語法啊~~~
寫到眼睛都花了...